#pragma once
#include "gp_TrsfForm.h"
#include "gp_Mat2d.h"
#include "gp_XY.h"

class gp_GTrsf2d;
class gp_Trsf;
class gp_Pnt2d;
class gp_Ax2d;
class gp_Vec2d;
class gp_XY;
class gp_Mat2d;


//!  Defines a non-persistent transformation in 2D space. <br>
//!  The following transformations are implemented : <br>
//!  . Translation, Rotation, Scale <br>
//!  . Symmetry with respect to a point and a line. <br>
//!  Complex transformations can be obtained by combining the <br>
//!  previous elementary transformations using the method Multiply. <br>
//!  The transformations can be represented as follow : <br>
//! <br>
//!       V1   V2   T       XY        XY <br>
//!    | a11  a12  a13 |   | x |     | x'| <br>
//!    | a21  a22  a23 |   | y |     | y'| <br>
//!    |  0    0    1  |   | 1 |     | 1 | <br>
//! <br>
//!   where {V1, V2} defines the vectorial part of the transformation <br>
//!   and T defines the translation part of the transformation. <br>
class gp_Trsf2d  {

public:


  //! Returns identity transformation. <br>
      gp_Trsf2d();
  //! Creates a 2d transformation in the XY plane from a <br>
//!          3d transformation . <br>
      gp_Trsf2d(const gp_Trsf& T);
  
//!  Changes the transformation into a symmetrical transformation. <br>
//!  P is the center of the symmetry. <br>
        void SetMirror(const gp_Pnt2d& P) ;
  
//!  Changes the transformation into a symmetrical transformation. <br>
//!  A is the center of the axial symmetry. <br>
       void SetMirror(const gp_Ax2d& A) ;
  
//!  Changes the transformation into a rotation. <br>
//!  P is the rotation's center and Ang is the angular value of the <br>
//!  rotation in radian. <br>
        void SetRotation(const gp_Pnt2d& P,const double Ang) ;
  
//!  Changes the transformation into a scale. <br>
//!  P is the center of the scale and S is the scaling value. <br>
        void SetScale(const gp_Pnt2d& P,const double S) ;
  
//!  Changes a transformation allowing passage from the coordinate <br>
//!  system "FromSystem1" to the coordinate system "ToSystem2". <br>
       void SetTransformation(const gp_Ax2d& FromSystem1,const gp_Ax2d& ToSystem2) ;
  
//!  Changes the transformation allowing passage from the basic <br>
//!  coordinate system <br>
//!  {P(0.,0.,0.), VX (1.,0.,0.), VY (0.,1.,0.)} <br>
//!  to the local coordinate system defined with the Ax2d ToSystem. <br>
       void SetTransformation(const gp_Ax2d& ToSystem) ;
  
//!  Changes the transformation into a translation. <br>
//!  V is the vector of the translation. <br>
        void SetTranslation(const gp_Vec2d& V) ;
  
//!  Makes the transformation into a translation from <br>
//!  the point P1 to the point P2. <br>
        void SetTranslation(const gp_Pnt2d& P1,const gp_Pnt2d& P2) ;
  //!  Replaces the translation vector with V. <br>
       void SetTranslationPart(const gp_Vec2d& V) ;
  //!  Modifies the scale factor. <br>
       void SetScaleFactor(const double S) ;
  //! Returns true if the determinant of the vectorial part of <br>
//! this transformation is negative.. <br>
        bool IsNegative() const;
  
//!  Returns the nature of the transformation. It can be  an <br>
//! identity transformation, a rotation, a translation, a mirror <br>
//! (relative to a point or an axis), a scaling transformation, <br>
//! or a compound transformation. <br>
        gp_TrsfForm Form() const;
  //! Returns the scale factor. <br>
        double ScaleFactor() const;
  
//!  Returns the translation part of the transformation's matrix <br>
       const gp_XY& TranslationPart() const;
  
//!  Returns the vectorial part of the transformation. It is a <br>
//!  2*2 matrix which includes the scale factor. <br>
       gp_Mat2d VectorialPart() const;
  
//!  Returns the homogeneous vectorial part of the transformation. <br>
//!  It is a 2*2 matrix which doesn't include the scale factor. <br>
//!  The coefficients of this matrix must be multiplied by the <br>
//!  scale factor to obtain the coefficients of the transformation. <br>
       const gp_Mat2d& HVectorialPart() const;
  
//!  Returns the angle corresponding to the rotational component <br>
//!  of the transformation matrix (operation opposite to SetRotation()). <br>
       double RotationPart() const;
  
//!  Returns the coefficients of the transformation's matrix. <br>
//!  It is a 2 rows * 3 columns matrix. <br>
//! Raises OutOfRange if Row < 1 or Row > 2 or Col < 1 or Col > 3 <br>
        double Value(const int Row,const int Col) const;
  
       void Invert() ;
  
//!  Computes the reverse transformation. <br>
//!  Raises an exception if the matrix of the transformation <br>
//!  is not inversible, it means that the scale factor is lower <br>
//!  or equal to Resolution from package gp. <br>
        gp_Trsf2d Inverted() const;
  
        gp_Trsf2d Multiplied(const gp_Trsf2d& T) const;
      gp_Trsf2d operator *(const gp_Trsf2d& T) const
{
  return Multiplied(T);
}
  
//!  Computes the transformation composed from <T> and  <me>. <br>
//!  In a C++ implementation you can also write Tcomposed = <me> * T. <br>
//!  Example : <br>
//!      Trsf2d T1, T2, Tcomp; ............... <br>
//!      //composition : <br>
//!        Tcomp = T2.Multiplied(T1);         // or   (Tcomp = T2 * T1) <br>
//!      // transformation of a point <br>
//!        Pnt2d P1(10.,3.,4.); <br>
//!        Pnt2d P2 = P1.Transformed(Tcomp);  //using Tcomp <br>
//!        Pnt2d P3 = P1.Transformed(T1);     //using T1 then T2 <br>
//!        P3.Transform(T2);                  // P3 = P2 !!! <br>
       void Multiply(const gp_Trsf2d& T) ;
    void operator *=(const gp_Trsf2d& T) 
{
  Multiply(T);
}
  
//!  Computes the transformation composed from <me> and T. <br>
//!  <me> = T * <me> <br>
       void PreMultiply(const gp_Trsf2d& T) ;
  
       void Power(const int N) ;
  
//!  Computes the following composition of transformations <br>
//!  <me> * <me> * .......* <me>,  N time. <br>
//!  if N = 0 <me> = Identity <br>
//!  if N < 0 <me> = <me>.Inverse() *...........* <me>.Inverse(). <br>
//! <br>
//!  Raises if N < 0 and if the matrix of the transformation not <br>
//!  inversible. <br>
        gp_Trsf2d Powered(const int N) ;
  
        void Transforms(double& X,double& Y) const;
  //! Transforms  a doublet XY with a Trsf2d <br>
        void Transforms(gp_XY& Coord) const;
    double _CSFDB_Getgp_Trsf2dscale() const { return scale; }
    void _CSFDB_Setgp_Trsf2dscale(const double p) { scale = p; }
    gp_TrsfForm _CSFDB_Getgp_Trsf2dshape() const { return shape; }
    void _CSFDB_Setgp_Trsf2dshape(const gp_TrsfForm p) { shape = p; }
    const gp_Mat2d& _CSFDB_Getgp_Trsf2dmatrix() const { return matrix; }
    const gp_XY& _CSFDB_Getgp_Trsf2dloc() const { return loc; }

friend class gp_GTrsf2d;


protected:




private: 


double scale;
gp_TrsfForm shape;
gp_Mat2d matrix;
gp_XY loc;


};






// other  functions and methods (like "C++: function call" methods)



